package com.kai.steering.data.service.service.impl;

import com.kai.steering.common.web.vo.ReturnCodeExt;
import com.kai.steering.data.service.entity.AnswerResult;
import com.kai.steering.data.service.entity.domainObject.*;
import com.kai.steering.data.service.entity.dto.AnswerQueryDTO;
import com.kai.steering.data.service.entity.po.Answer;
import com.kai.steering.data.service.entity.vo.AnswerVO;
import com.kai.steering.data.service.mapper.AnswerMapper;
import com.kai.steering.data.service.service.*;
import com.kai.steering.common.web.service.impl.BaseServiceImpl;
import com.kai.steering.common.vo.Page;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;

import java.io.Serializable;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;

/**
 * <pre>
 * 答案 服务实现类
 * </pre>
 *
 * @author kai
 * @since 2022-02-23
 */
@Slf4j
@Service
public class AnswerServiceImpl extends BaseServiceImpl<AnswerMapper, Answer> implements AnswerService {

    @Autowired
    private AnswerMapper answerMapper;
    @Autowired
    private QuestionService questionService;
    @Autowired
    private UserQuestionService userQuestionService;
    @Autowired
    VerdictAnswerService verdictAnswerService;
    @Autowired
    AnswerJournalService answerJournalService;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public AnswerDO saveAnswer(AnswerDO answerDO) {
        if (answerDO == null) {
            return null;
        }


        if (answerDO.getQuestionId() == null || questionService.getQuestionById(answerDO.getQuestionId(), null) == null) {
            throw ReturnCodeExt.PARAMETER_CHECK.getException("答案的questionId不存在");

        }
        Answer answer = new Answer(answerDO);
        answer.setCreationDatetime(new Date());
        answer.setAnswerId(null);
        if (super.save(answer)) {
            return new AnswerDO(answer);
        }

        return new AnswerDO();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<AnswerDO> saveAnswerBatch(List<AnswerDO> answerDOs) {
        if (answerDOs == null) {
            return null;
        }
        List<Answer> collect = answerDOs.stream().map(answerDO -> {
            answerDO.setCreationDatetime(new Date());
            answerDO.setDeleteDatetime(null);
            answerDO.setAnswerId(null);
            return new Answer(answerDO);
        }).collect(Collectors.toList());
        boolean b = this.saveBatch(collect);
        if (b) {
            return collect.stream().map(answer -> {
                return new AnswerDO(answer);
            }).collect(Collectors.toList());
        } else {
            return new ArrayList<>();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateAnswer(Serializable id, AnswerDO answerDO) {
        AnswerDO answerById = getAnswerById(id);
        if (answerById == null || answerById.getAnswerId() == null) {
            throw ReturnCodeExt.PARAMETER_CHECK.getException("对象[" + id + "]不存在");
        }
        answerDO.setAnswerId(id.toString());

        Answer answer = new Answer(answerDO);

        return super.updateById(answer);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteAnswer(Serializable id) {
        AnswerDO answerById = getAnswerById(id);
        if (answerById == null || answerById.getAnswerId() == null) {
            throw ReturnCodeExt.PARAMETER_CHECK.getException("对象[" + id + "]不存在");
        }
        super.removeById(id);
        return true;
    }

    @Override
    public AnswerDO getAnswerById(Serializable answerId) {
        /**
         * 获取数据
         */
        Answer answer = super.getById(answerId);
        /**
         * 校验数据
         */
        if (answer == null || answer.getAnswerId() == null) {
            return null;
        }
        /**
         * 构建对象
         */
        AnswerDO answerDO = new AnswerDO(answer);

        return answerDO;
    }

    @Override
    public List<AnswerDO> getAnswerByQId(Serializable questionId) {
        QueryWrapper<Answer> qw = new QueryWrapper<>();
        qw.eq("question_id", questionId);
        List<Answer> list = super.list(qw);
        List<AnswerDO> collect = list.stream().map(answer -> {
            return new AnswerDO(answer);
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public Map<String, AnswerDO> getAnswerByQId(List<String> answerIds){
        QueryWrapper<Answer> qw = new QueryWrapper<>();
        qw.in("answer_id", answerIds);
        List<Answer> list = super.list(qw);
        Map<String, AnswerDO> stringAnswerHashMap = new HashMap<>();
        List<AnswerDO> collect = list.stream().map(answer -> {
            return new AnswerDO(answer);
        }).collect(Collectors.toList());
        if (collect!=null ||collect.size()>0) {
            // 使用Stream API转换为Map
            stringAnswerHashMap = collect.stream()
                    .collect(Collectors.toMap(AnswerDO::getQuestionId, Function.identity()));

        }

        return stringAnswerHashMap;
    }


    @Override
    public List<AnswerVO> getAllAnswer() {
        List<Answer> answerlist = answerMapper.selectList(new QueryWrapper<Answer>());
        List<AnswerVO> result = answerlist.stream()
                .map(answer -> {
                    AnswerVO answerVo = new AnswerVO();
                    BeanUtil.copyProperties(answer, answerVo);
                    return answerVo;
                })
                .collect(Collectors.toList());
        return result;
    }

    @Override
    public Page<AnswerVO> getAnswerPageList(AnswerQueryDTO answerQueryDTO) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page = setPageParam(
                answerQueryDTO, OrderItem.desc("create_time")
        );

        QueryWrapper<Answer> queryWrapper = new QueryWrapper<>();

        //组合条件
        IPage<Answer> entityPage = answerMapper.selectPage(page, queryWrapper);
        List<AnswerVO> result = entityPage.getRecords().stream()
                .map(answer -> {
                    AnswerVO answerVo = new AnswerVO();
                    BeanUtil.copyProperties(answer, answerVo);
                    return answerVo;
                })
                .collect(Collectors.toList());

        return Page.<AnswerVO>builder()
                .currPage(answerQueryDTO.getPageNo())
                .pageSize(answerQueryDTO.getPageSize())
                .totalCount((int) entityPage.getTotal())
                .list(result)
                .build();
    }


    @Override
    public boolean isExists(String key, String val, Serializable id) {
        QueryWrapper<Answer> qw = new QueryWrapper<>();
        qw.eq(key, val);
        if (id != null) {
            qw.ne("id", id);
        }
        int num = this.count(qw);
        return num > 0;
    }

    @Override
    public AnswerResult replyAnswer(AnswerDO answerDO) {
        /**
         * 参数检查
         */
        if (answerDO.getQuestionId() == null) {
            throw ReturnCodeExt.PARAMETER_CHECK.getException("对象answerDO[QuestionId]为空");
        }
        QuestionDO questionById = questionService.getQuestionById(answerDO.getQuestionId(), null);

        if (questionById == null || questionById.getQuestionId() == null) {
            throw ReturnCodeExt.PARAMETER_CHECK.getException("对象answerDO[" + answerDO.getQuestionId() + "]不存在");
        }
        if (questionById.getStandardAnswer() == null) {
            throw ReturnCodeExt.PARAMETER_CHECK.getException("对象answerDO[答案]不存在");
        }

        /**
         * 构建对象
         */

        //校验
        AnswerResult answerResult = verdictAnswerService.verdict(questionById.getClassificationDO(), answerDO, questionById.getStandardAnswer());
        answerResult.setAnswer(questionById.getStandardAnswer());
        /**
         * 记录
         */
        //数据处理
        UserQuestionDO userQuestionDO = userQuestionService.updateQuestionData(questionById.getQuestionId(), answerResult.getResult() == 100 ? 1 : 0);


        //日志处理
        AnswerJournalDO answerJournalDO = new AnswerJournalDO(answerDO,questionById,answerResult,userQuestionDO);
        answerJournalService.saveAnswerJournal(answerJournalDO);
        return answerResult;
    }


}

